﻿using System;
using System.Collections.Generic;
using System.Text;
using Psm.Client;
using Psm.PubSub.StateCache;
using Psm.Messaging;
using System.Threading;
using Psm.PubSub.Messaging;

namespace Psm.PubSub.Client
{
    public class PubSubClient : IMessageCallback
    {
        private IMessageCallback messageCallback;
        private PsmClient client;
        private ManualResetEvent syncEvent = new ManualResetEvent(false); 

        public PubSubClient(string configName, IMessageCallback callback)
        {
            this.messageCallback = callback;
            client = new PsmClient(configName, this);
            syncEvent.WaitOne();
        }

        public void SendMessage(IMessage message)
        {
            this.client.SendMessage(message);
        }

        public void Close()
        {
            this.client.Close();
        }

        public void NewMessage(IMessage message)
        {
            if (message is DataMessage)
            {
                if (messageCallback != null) messageCallback.NewMessage(message);
            }
            else if (message is SchemaMessage)
            {
                SchemaMessage schemaMessage = message as SchemaMessage;
                if (string.IsNullOrEmpty(schemaMessage.Schema.Topic))
                    syncEvent.Set();
                else
                {
                    SchemaCollection.AllSchemas.Add(schemaMessage.Schema.Topic, schemaMessage.Schema);
                }
            }
        }

        public DataMessage CreateDataMessage(string topic)
        {
            if (string.IsNullOrEmpty(topic)) throw new ArgumentNullException("topic");
            if( SchemaCollection.AllSchemas.Keys.Contains(topic) )
                return new DataMessage(SchemaCollection.AllSchemas[topic]);
            throw new Exception(string.Format("Schema for topic {0} not found", topic));
        }

        public QueryMessage CreateQueryMessage(string topic)
        {
            if (string.IsNullOrEmpty(topic)) throw new ArgumentNullException("topic");
            if (SchemaCollection.AllSchemas.Keys.Contains(topic))
                return new QueryMessage(SchemaCollection.AllSchemas[topic]);
            throw new Exception(string.Format("Schema for topic {0} not found", topic));
        }

        public void Flush()
        {
            this.client.Flush();
        }
    }
}
